﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace Nature.Toolkit.GMix
{
    internal class MixProjectionEnumerator : IEnumerator<MixProjection>
    {
        #region Private Fields

        private MixCrossJoin m_allPossibleParameterCombinations;
        private MixProjection m_current;
        private IEnumerator<double[]> m_enumerator;

        #endregion

        #region Constructors
        internal MixProjectionEnumerator(ExpressionInfo expression)
        {
            this.Expression = expression;
            m_allPossibleParameterCombinations = new MixCrossJoin(expression.Parameters);
            m_enumerator = m_allPossibleParameterCombinations.GetEnumerator();
        } 
        #endregion

        internal ExpressionInfo Expression
        {
            get;
            private set;
        }

        private MixProjection ResolveCurrent()
        {
            MixProjection projection = new MixProjection(Expression);

            for (int i = 0; i < Expression.Parameters.Length; ++i)
            {
                projection.SetParameterValue(i, m_enumerator.Current[i]);
            }
            projection.Fill();
            return projection;
        }

        #region IEnumerator<MixDataProjection> Members

        MixProjection IEnumerator<MixProjection>.Current
        {
            get 
            {
                if (m_current == null)
                {
                    m_current = ResolveCurrent();
                }
                return m_current;
            }
        }

        #endregion

        #region IDisposable Members

        void IDisposable.Dispose() { }

        #endregion

        #region IEnumerator Members

        object System.Collections.IEnumerator.Current
        {
            get 
            {
                if (m_current == null)
                {
                    m_current = ResolveCurrent();
                }
                return m_current;
            }
        }

        bool System.Collections.IEnumerator.MoveNext()
        {
            m_current = null;
            bool moveNextResult = m_enumerator.MoveNext();
            return moveNextResult;
        }

        void System.Collections.IEnumerator.Reset()
        {
            m_current = null;
            m_enumerator.Reset();
        }

        #endregion
    }
}
